package com.d3.pomodoro.utils

import androidx.fragment.app.Fragment
import java.util.*

open class FragmentUserVisibleController(
    fragment: Fragment,
    userVisibleCallback: UserVisibleCallback
) {
    private val TAG = "FragmentUserVisibleController"
    private var fragmentName: String = ""
    private var waitingShowToUser: Boolean = false
    private lateinit var fragment: Fragment
    private lateinit var userVisibleCallback: UserVisibleCallback
    private var userVisibleListenerList: MutableList<OnUserVisibleListener>? = null

    init {
        this.fragment = fragment
        this.userVisibleCallback = userVisibleCallback
        this.fragmentName = fragment.javaClass.name
    }

    fun activityCreated() {
        if (fragment.userVisibleHint) {
            val parentFragment = fragment.parentFragment
            if (parentFragment != null && !parentFragment.userVisibleHint) {
                userVisibleCallback.isWaitingShowToUser = true
                userVisibleCallback.callSuperSetUserVisibleHint(false)
            }
        }
    }

    fun resume() {
        if (fragment.userVisibleHint) {
            userVisibleCallback.onVisibleToUserChanged(
                isVisibleToUser = true,
                invokeInResumeOrPause = true
            )
            callbackListener(isVisibleToUser = true, invokeInResumeOrPause = true)
        }
    }

    fun pause() {
        if (fragment.userVisibleHint) {
            userVisibleCallback.onVisibleToUserChanged(
                isVisibleToUser = false,
                invokeInResumeOrPause = true
            )
            callbackListener(isVisibleToUser = false, invokeInResumeOrPause = true)
        }
    }

    fun setUserVisibleHint(isVisibleToUser: Boolean) {
        val parentFragment = fragment.parentFragment

        // 父Fragment还没显示，你着什么急
        if (isVisibleToUser) {
            if (parentFragment != null && !parentFragment.userVisibleHint) {
                userVisibleCallback.isWaitingShowToUser = true
                userVisibleCallback.callSuperSetUserVisibleHint(false)
                return
            }
        }

        if (fragment.isResumed) {
            userVisibleCallback.onVisibleToUserChanged(isVisibleToUser, false)
            callbackListener(isVisibleToUser, false)
        }

        if (fragment.activity != null) {
            val childFragmentList = fragment.childFragmentManager.fragments
            if (isVisibleToUser) {
                // 显示待显示的子Fragment
                if (childFragmentList.size > 0) {
                    for (childFragment in childFragmentList) {
                        if (childFragment is UserVisibleCallback) {
                            val userVisibleCallback = childFragment as UserVisibleCallback
                            if (userVisibleCallback.isWaitingShowToUser) {
                                userVisibleCallback.isWaitingShowToUser = false
                                childFragment.userVisibleHint = true
                            }
                        }
                    }
                }
            } else {
                // 隐藏正在显示的子Fragment
                if (childFragmentList.size > 0) {
                    for (childFragment in childFragmentList) {
                        if (childFragment is UserVisibleCallback) {
                            val userVisibleCallback = childFragment as UserVisibleCallback
                            if (childFragment.userVisibleHint) {
                                userVisibleCallback.isWaitingShowToUser = true
                                childFragment.userVisibleHint = false
                            }
                        }
                    }
                }
            }
        }
    }

    private fun callbackListener(isVisibleToUser: Boolean, invokeInResumeOrPause: Boolean) {
        if (userVisibleListenerList != null && userVisibleListenerList!!.size > 0) {
            for (listener in userVisibleListenerList!!) {
                listener.onVisibleToUserChanged(isVisibleToUser, invokeInResumeOrPause)
            }
        }
    }

    /**
     * 当前Fragment是否对用户可见
     */
    fun isVisibleToUser(): Boolean {
        return fragment.isResumed && fragment.userVisibleHint
    }

    fun isWaitingShowToUser(): Boolean {
        return waitingShowToUser
    }

    fun setWaitingShowToUser(waitingShowToUser: Boolean) {
        this.waitingShowToUser = waitingShowToUser
    }

    fun addOnUserVisibleListener(listener: OnUserVisibleListener?) {
        if (listener != null) {
            if (userVisibleListenerList == null) {
                userVisibleListenerList = LinkedList()
            }
            userVisibleListenerList!!.add(listener)
        }
    }

    fun removeOnUserVisibleListener(listener: OnUserVisibleListener?) {
        if (listener != null && userVisibleListenerList != null) {
            userVisibleListenerList!!.remove(listener)
        }
    }

    interface UserVisibleCallback {
        var isWaitingShowToUser: Boolean

        val isVisibleToUser: Boolean

        fun callSuperSetUserVisibleHint(isVisibleToUser: Boolean)

        /**
         * 当Fragment对用户的可见性发生了改变的时候就会回调此方法
         * <br></br>
         * 参考链接：http://www.jianshu.com/p/850556d33f63
         *
         * @param isVisibleToUser       true：用户能看见当前Fragment；false：用户看不见当前Fragment
         * @param invokeInResumeOrPause true：发生在onResume或onPause方法里，false：本次回调发生在setUserVisibleHintMethod方法里；
         */
        fun onVisibleToUserChanged(isVisibleToUser: Boolean, invokeInResumeOrPause: Boolean)
    }

    interface OnUserVisibleListener {
        /**
         * 当Fragment对用户的可见性发生了改变的时候就会回调此方法
         * <br></br>
         * 参考链接：http://www.jianshu.com/p/850556d33f63
         *
         * @param isVisibleToUser       true：用户能看见当前Fragment；false：用户看不见当前Fragment
         * @param invokeInResumeOrPause true：发生在onResume或onPause方法里，false：本次回调发生在setUserVisibleHintMethod方法里；
         */
        fun onVisibleToUserChanged(isVisibleToUser: Boolean, invokeInResumeOrPause: Boolean)
    }
}